﻿using System;

namespace TwinHead
{
    /// <summary>
    /// 열거형식에 대한 확장입니다.
    /// </summary>
    public static class EnumerationExtensions
    {
        /// <summary>
        /// 현재 열거형내에 지정한 T가 포함되어 있습니까?
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool Has<T>( this System.Enum type, T value )
        {
            try
            {
                return (((ulong)(object)type & (ulong)(object)value) == (ulong)(object)value);
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 현재 열거형이 지정한 T와 동치입니까?
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool Is<T>( this System.Enum type, T value )
        {
            try
            {
                return (ulong)(object)type == (ulong)(object)value;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 현재 열거형에 T값을 포함시킵니다.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T Add<T>( this System.Enum type, T value )
        {
            try
            {
                return (T)(object)(((ulong)(object)type | (ulong)(object)value));
            }
            catch (Exception ex)
            {
                throw new ArgumentException(
                    string.Format(
                        "Could not append value from enumerated type '{0}'.",
                        typeof( T ).Name
                        ), ex );
            }
        }
        /// <summary>
        /// 현재 열거형에서 T값을 제거합니다
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T Remove<T>( this System.Enum type, T value )
        {
            try
            {
                return (T)(object)(((ulong)(object)type & ~(ulong)(object)value));
            }
            catch (Exception ex)
            {
                throw new ArgumentException(
                    string.Format(
                        "Could not remove value from enumerated type '{0}'.",
                        typeof( T ).Name
                        ), ex );
            }
        }
    }
}
